<?php

/**
 * Klasa do obslugi bazy sqlite
 *
 */
class DbSqlLite implements DBConnection {
    protected $user;
    protected $pass;
    protected $dbHost;
    protected $dbName;
    protected $dbh;
    protected $fileName;
    protected $mode = '0666';
    protected $characterset = 'utf8';

    /**
     * Konstruktor klasy
     *
     * @param string $user
     * @param string $pass
     * @param string $dbHost
     * @param string $dbName
     */
    public function __construct($file) {
	$this->fileName = $file;
    }
    /*Nawiazywanie polaczenia z baza*/
    protected function Connect() {


		try {
			$this->DbConnect();
			$this->SetCharacterset();
		} catch (Exception $e) {
			MFLog::Fatal("Line: ".$e->getLine()." Message: ".$e->getMessage()." Referer: ".getenv('HTTP_REFERER'));
			MFLog::Error("Switching app to safe mode");
			Core::SetAppSafeMode();
		}


    }

	protected function DbConnect() {
		$this->dbh = sqlite_open($this->fileName, $this->mode, $errorMessage);
	if(empty($this->dbh)) {
            throw new CoreException('Cannot connect to database! '.$errorMessage);
        }
	}



	protected function SetCharacterset() {
	//sqlite_query($this->dbh, "SET CHARACTER SET ".$this->characterset);
        //sqlite_query($this->dbh, "SET NAMES '".$this->characterset."'");
        //sqlite_query($this->dbh, "SET CHARACTER_SET_CLIENT = ".$this->characterset);
        //sqlite_query($this->dbh, "SET character_set_results = ".$this->characterset);
        //sqlite_query($this->dbh, "SET character_set_connection = ".$this->characterset);
	}

	public function Escape($string) {

	    if(Enviroment::CheckMagicQuotes()) {
		$return = $string;
	    } else {
		$return = sqlite_escape_string($string);
	    }

	    return $return;
	}

    /*Wykonanie zapytania*/
    public function Execute($query) {

        if(!$this->dbh) {
            $this->Connect();
        }
		MFLog::Debug($query);
		$ret = 'unexecuted';
		if($this->dbh) {
			$ret = sqlite_query($this->dbh, $query);
		}
        if(!$ret && $ret!='unexecuted') {
            throw new CoreException(sqlite_error_string(sqlite_last_error($this->dbh)).$query);
        }
        else {
            $stmt = new DbSqlLiteStatement($this->dbh, $query);
            $stmt->result = $ret;
            return $stmt;
        }
    }
    /*Przygotowanie zapytania zwraca obiekt klasy DBMysqlStatement*/
    public function Prepare($query) {
        if(!$this->dbh) {
            $this->Connect();
        }
        return new DbSqlLiteStatement($this->dbh, $query);
    }

    /**
     * Rozpoczyna transakcje
     *
     */
    public function BeginTransaction() {
        if(!$this->dbh) {
            $this->Connect();
        }
        @sqlite_query("START TRANSACTION ");
    }

    /**
     * Zartwierdza transakcje
     *
     */
    public function CommitTransaction() {
        if(!$this->dbh) {
            $this->Connect();
        }
        @sqlite_query("COMMIT");
    }

    /**
     * Wycofuje transakcje
     *
     */
    public function Rollback() {
        if(!$this->dbh) {
            $this->Connect();
        }
        @sqlite_query("ROLLBACK");
    }

    /**
     * Destruktor zamykajacy polaczenie
     *
     */
    public function __destruct() {
        if(isset($this->dbh) && is_resource($this->dbh)) {
            sqlite_close($this->dbh);
        }
    }
	public function GetDbh() {
		return $this->dbh;
	}

}

/**
 * Klasa implementujaca interfejs DBStatement dla mysqla
 *
 */
class DbSqlLiteStatement implements DBStatement {
    public $result;
    public $binds;
    public $query;
    public $dbh;
    private $cacheTime = 30;
    private $cacheFile;
    private $cachePath = DBCACHE_PATH;
    private $cacheEnable = DBCACHE_ENABLE;
    private $cacheQuery = false;

    /**
     * KOnstruktor klasy
     *
     * @param mysql $dbh
     * @param string $query
     */
    public function __construct($dbh, $query) {
        $this->query = $query;
        $this->dbh = $dbh;
        if(!$dbh) {
			Core::SetAppSafeMode();
            //throw new MysqlException("No db connection");

        }
    }

    /**
     * Zwraca tresc zapytania
     *
     * @return unknown
     */
    public function GetQuery()
    {
        return $this->query;
    }
    /*Zamienia zmienne w zapytaniu na podane wartosci*/
    public function BindParam($ph, $pv) {
        $this->binds[$ph] = $pv;
        return $this;
    }
    /*Wykonanie zapytania*/
    public function Execute() {

        $binds = func_get_args();
        foreach($binds as $index => $name) {
            $this->binds[$index + 1] = $name;
        }
        $cnt = count($binds);
        $query = $this->query;

        if (count($this->binds)>0) {
            foreach ($this->binds as $ph => $pv) {
//                $query = str_replace(":$ph", "'".mysql_escape_string($pv)."'", $query);
				$query = str_replace(":$ph", '\''.sqlite_escape_string($pv).'\'', $query);
            }
        }
		MFLog::Debug(__FUNCTION__.' query: '.$query);
		if($this->dbh) {
        $this->result = sqlite_query($this->dbh, $query);

        if(!$this->result) {
            throw new MysqlException($query . "<br /><br />" . mysql_error());
        }
		}
        return $this;
    }
    /*Zwraca wiersz*/
    public function FetchRow() {
        if(!$this->result) {
            throw new MysqlException("Query failed");
        }
        $this->SetCacheFile($this->query.'FetchRow');

        if($this->cacheQuery==false) {
            $result = sqlite_fetch_row($this->result);
        }

        else if ($this->cacheQuery==true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
            $result = sqlite_fetch_row($this->result);
            $this->CacheWrite($result);
        } else {
            $result = $this->CacheRead();
        }

        return $result;
    }
    /*Zwraca wiersz jako tablice asocjacyjna*/
    public function FetchAssoc() {
        $this->SetCacheFile($this->query.'FetchAssoc');

        if($this->cacheQuery==false) {
            $result = sqlite_fetch_assoc($this->result);
        }

		else if(($this->cacheQuery==true && !$this->CacheCheck() && !Core::GetAppSafeMode())) {
            $result = sqlite_fetch_assoc($this->result);
            $this->CacheWrite($result);
        } else {
            $result = $this->CacheRead();
        }

        return $result;
    }
    /*Zwraca ca�y wynik jako tablica asocjacyjna*/
    public function FetchAllAssoc() {
		$this->SetCacheFile($this->query.'FetchAllAssoc');

        if($this->cacheQuery==false) {
            $result = array();

            while($row = $this->fetchAssoc()) {
                $result[] = $row;
            }
        }

        else if($this->cacheQuery==true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
            $result = array();
            $this->cacheQuery = false;
            while($row = $this->fetchAssoc()) {
                $result[] = $row;
            }
			$this->SetCacheFile($this->query.'FetchAllAssoc');
            $this->CacheWrite($result);
        } else {
            $result = $this->CacheRead();
        }

        return $result;

    }
    /*Zwraca ca�y wynik jako tablica asocjacyjna*/
    public function FetchAllRow() {
        $this->SetCacheFile($this->query.'FetchAllRow');



        if($this->cacheQuery==false) {
            $result = array();

            while($row = $this->fetchRow()) {
                $result[] = $row;
            }
        }

        else if($this->cacheQuery==true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
            $result = array();
            $this->cacheQuery = false;
            while($row = $this->fetchRow()) {
                $result[] = $row;
            }
			$this->SetCacheFile($this->query.'FetchAllRow');
            $this->CacheWrite($result);
        } else {
            $result = $this->CacheRead();
        }

        return $result;
    }
    /*Zwraca liczbe wierszy*/
    public function NumRows() {
        if(!$this->result) {
            throw new MysqlException("Query failed");
        }
        $this->SetCacheFile($this->query.'NumRows');

        if($this->cacheQuery==false) {
            $result = sqlite_num_rows($this->result);

        }

        else if($this->cacheQuery==true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
            $result = sqlite_num_rows($this->result);
            $this->CacheWrite($result);
        } else {
            $result = $this->CacheRead();
        }

        return $result;
    }
    /*Zwraca wiersz w postaci tablicy*/
    public function FetchArray() {
        if(!$this->result) {
            throw new MysqlException("Query failed");
        }
        $this->SetCacheFile($this->query.'FetchArray');



        if($this->cacheQuery==false) {
            $result = sqlite_fetch_array($this->result);

        }

        else if($this->cacheQuery==true && !$this->CacheCheck() && !Core::GetAppSafeMode()) {
            $result = sqlite_fetch_array($this->result);
            $this->CacheWrite($result);
        } else {
            $result = $this->CacheRead();
        }

        return $result;
    }
    /**
     * Zwraca id ostatnio zmienionego rekordu
     *
     * @return integer
     */
    public function GetInsertionId() {
        if(!$this->result) {
            throw new MysqlException("Query failed");
        }
		return sqlite_last_insert_rowid($this->dbh);
    }

    /**
     * Zwraca liczb� zmienionych rekord�w w ostatnim zapytaniu modyfikuj�cym dane.
     *
     * @return integer
     */
    public function GetAffectedRows()
    {
        if(!$this->result) {
            throw new MysqlException("Query failed");
        }
        return sqlite_affected_rows();

    }

    /**
     * Sprawdza czy zaoytanie jest cacheowane
     *
     * @return boolean
     */
    public function CacheCheck() {
        if($this->cacheEnable == false || ($this->cacheEnable == true && (is_file($this->cachePath.$this->cacheFile) && filemtime($this->cachePath.$this->cacheFile) > (time() - $this->cacheTime)))) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Zapisuje cache do pliku
     *
     * @param obj $result
     */
    public function CacheWrite($result) {
        if($this->cacheEnable != false) {
            $records = serialize($result);
            $fp = fopen($this->cachePath.$this->cacheFile, "w");
            fputs($fp, $records);
            fclose($fp);
            $this->cacheQuery = false;
        }

    }

    /**
     * Odczytuje cache z pliku
     *
     * @return obj
     */
    public function CacheRead() {
		if(is_file($this->cachePath.$this->cacheFile)) {
        $records = unserialize(file_get_contents($this->cachePath.$this->cacheFile));
        $this->cacheQuery = false;
        return $records;
		} else {
			throw new MysqlException('File does not exist: '.$this->cachePath.$this->cacheFile);
		}
    }

    /**
     * Uruchamia cacheowanie
     *
     * @param integer $time
     */
    public function CacheStart($time=null) {
        if($time!=null && $this->cacheEnable != false) {
            $this->cacheTime = $time;
        }
		if($this->cacheEnable != false)
			$this->cacheQuery = true;
		else
			$this->cacheQuery = false;

		return $this;
    }

    /**
     * Ustanawia nazw� pliku cache
     *
     * @param unknown_type $fileName
     */
    public function SetCacheFile($fileName) {
		$this->cacheFile=md5($fileName);
    }




}

class DBTemp extends DbSqlLite {

    /**
     * Pusty konstruktor
     *
     */
	public function __construct() {
	    $this->fileName = '../SqlLite/sql';
	}



    public function GetDbh() {
        if(empty($this->dbh)) {
            $this->Connect();
        }
        return $this->dbh;
    }
}

